/*
 * @Author: hulu20 - 563293401@qq.com
 * @Date: 2023-02-11 19:38:24
 * @Last Modified by: hulu20 - 563293401@qq.com
 * @Last Modified time: 2023-02-15 16:14:52
 * @Desc: 注册指标
 */
package service

import (
	"context"
	"tasktor/internal/logic"
	"tasktor/library/liberr"
	"time"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
)

var (
	MetricsService = metricsImpl{} // 对外提供方法，变量大写
)

type metricsImpl struct{}

func (s *metricsImpl) RecordMetrics(ctx context.Context) {

	// 任务指标获取 - 开启携程进行数据获取
	// 如果使用prometheus.NewCounter 还需额外进行指标注册 prometheus.MustRegister
	taskStatus := promauto.NewGaugeVec(prometheus.GaugeOpts{
		Name: "task_monitor_status",
		Help: "the task monitor info",
	}, []string{"name", "tag", "username", "status", "shCount", "acCount", "startAt"})

	// taskShCount := promauto.NewGaugeVec(prometheus.GaugeOpts{
	// 	Name: "task_monitor_shCount",
	// 	Help: "the task monitor shCount",
	// }, []string{"name", "username"})

	// taskAcCount := promauto.NewGaugeVec(prometheus.GaugeOpts{
	// 	Name: "task_monitor_acCount",
	// 	Help: "the task monitor acCount",
	// }, []string{"name", "username"})

	taskExTime := promauto.NewGaugeVec(prometheus.GaugeOpts{
		Name: "task_monitor_exTime",
		Help: "the task monitor exTime",
	}, []string{"name", "tag", "username", "status"})

	// sleep 模式定时，执行时间 = 程序时间 + sleep 时间
	go func() {
		for {
			var (
				vStatus string
				exTime  int64
			)
			// 刷新时间获取
			refTime, err := g.Cfg().Get(ctx, "task.refTime")
			liberr.ErrIsNil(ctx, err, "获取刷新时间失败")
			preDay, err := g.Cfg().Get(ctx, "task.preDay")
			liberr.ErrIsNil(ctx, err, "获取间隔时间失败")

			preTime := gtime.Now().AddDate(0, 0, gconv.Int(preDay)).Unix() // N天前时间戳
			nowTime := gtime.Timestamp()                                   // 当前时间戳

			// 获取任务数据
			taskDate, _ := logic.TaskMonitorLogic.GetMonitorData(ctx, preTime)

			// 重置指标
			taskStatus.Reset()
			taskExTime.Reset()

			// 循环处理每个任务状态
			for _, v := range taskDate {
				// 状态判断
				switch {
				case v.Status == 1:
					vStatus = "success"
				case v.Status == 2:
					vStatus = "fail"
				default:
					vStatus = "runing"
				}

				// 获取任务开始时间，如果任务正在运行中，计算出执行时间，如果已经执行完成或失败，统计总时间/s
				if v.Status == 1 || v.Status == 2 {
					exTime = v.EndAt - v.StartAt
				} else {
					exTime = nowTime - v.StartAt
				}

				// task_monitor_status
				taskStatus.WithLabelValues(v.TaskName, v.TaskTag, v.Username, vStatus, gconv.String(v.ShouldCount), gconv.String(v.ActualCount), gconv.String(v.StartAt*1000)).Set(gconv.Float64(v.Status))

				// task_monitor_exTime
				taskExTime.WithLabelValues(v.TaskName, v.TaskTag, v.Username, vStatus).Set(gconv.Float64(exTime))
			}

			// 间隔时间
			time.Sleep(gconv.Duration(refTime) * time.Second)
		}
	}()

	// // gtimer 测试 -- 不能热更新配置
	// // 任务获取刷新时间
	// refTime, err := g.Cfg().Get(ctx, "task.refTime")
	// liberr.ErrIsNil(ctx, err, "获取刷新时间失败")
	// refTime2 := gconv.Duration(refTime) * time.Second

	// gtimer.AddEntry(ctx, refTime2, func(ctx context.Context) {
	// 	// 获取任务数据
	// 	taskDate, _ := logic.TaskMonitorLogic.GetMonitorData(ctx, 1676080362)
	// 	for _, v := range taskDate {
	// 		taskOption.WithLabelValues(v.TaskName, v.Username, gconv.String(v.ShouldCount), gconv.String(v.ActualCount)).Set(gconv.Float64(v.Status))
	// 	}
	// }, true, 0, 0)

}
